﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MicroService.APIGateway
{
    public class RequestLog
    {
        private readonly RequestDelegate _next;

        private readonly ILogger _logger;

        /// <summary>
        /// 管道执行到该中间件时候下一个中间件的RequestDelegate请求委托，如果有其它参数，也同样通过注入的方式获得
        /// </summary>
        /// <param name="next"></param>
        public RequestLog(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<RequestLog>();
            //通过注入方式获得对象
            _next = next;
        }

        /// <summary>
        /// 自定义中间件要执行的逻辑
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public  Task Invoke(HttpContext context)
        {
            var orgBodyStream = context.Response.BodyWriter.AsStream();//获取body内容
            var ms = new MemoryStream();
            ms.Seek(0, SeekOrigin.Begin);
            using (var sr = new StreamReader(ms))//
            {
                string newContent = sr.ReadToEnd();
                _logger.LogInformation($"Client Ip:{context.Connection.RemoteIpAddress.ToString()};{context.Request.Method}:{context.Request.Path};{newContent}");
                //if (newContent.Contains("ceo"))
                //{
                //    byte[] content = Encoding.UTF8.GetBytes(newContent.Replace("ceo", "CEO"));
                //    ms.Write(content, 0, content.Length);
                //    ms.Seek(0, SeekOrigin.Begin);
                //}
                //await ms.CopyToAsync(orgBodyStream);
            }
            //Console.WriteLine("Request1:"+ context.Request.QueryString);//请求进来时逻辑，为了验证顺序性，打印一句话
            //_logger.LogInformation($"Client Ip:{context.Connection.RemoteIpAddress.ToString()};{context.Request.Method}:{context.Request.Path};{context.Response.Body}");
          
            return _next(context);//把context传进去执行下一个中间件
        }
    }

    public static class IPMiddlewareExtensions
    {
        public static IApplicationBuilder UseRequestLog(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<RequestLog>();
        }
    }

}
